package com.launcher;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;

import com.launcher.decorator.Engine;
import com.launcher.decorator.Fairring;
import com.launcher.decorator.RocketDecorator;
import com.launcher.decorator.Stage;

public class RocketHibernateDAO implements IRocketDAO
{
	private static RocketHibernateDAO instance = new RocketHibernateDAO();
	private Session session;
	
	private RocketHibernateDAO() 
	{
		SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
		session = sessionFactory.openSession();
		
		RocketHibernateDAO.instance = this;
	}
	
	public static RocketHibernateDAO getInstance()
	{
		return RocketHibernateDAO.instance;
	}
	
	@SuppressWarnings("unchecked")
	public List<PayLoad> getPayLoads()
	{
		List<PayLoad> list = session.createQuery("FROM PayLoad").list();
		
		return list;
	}

	@SuppressWarnings("unchecked")
	public Fairring getFairring(int height)
	{
		List<Fairring> fairrings = session.createQuery("FROM Fairring WHERE capability >= " + height + " GROUP BY cost ORDER BY capability ASC").list();

		return fairrings.get(0).clone();
	}
	
	@SuppressWarnings("unchecked")
	public List<Engine> getEngines()
	{
		List<Engine> temp = session.createQuery("FROM Engine GROUP BY cost").list();
		
		List<Engine> list = new ArrayList<Engine>();
		
		for (Engine e : temp)
		{
			list.add(e.clone());
		}
		
		return list;
	}
	
	@SuppressWarnings("unchecked")
	public List<Engine> getEnginesHL()
	{
		List<Engine> temp = session.createQuery("FROM Engine GROUP BY cost ORDER BY power DESC").list();

		List<Engine> list = new ArrayList<Engine>();
		
		for (Engine e : temp)
		{
			list.add(e.clone());
		}
		
		return list;
	}
	
	@SuppressWarnings("unchecked")
	public List<Fairring> getFairrings()
	{
		List<Fairring> temp = session.createQuery("FROM Fairring GROUP BY cost").list();

		List<Fairring> list = new ArrayList<Fairring>();
		
		for (Fairring e : temp)
		{
			list.add(e.clone());
		}
		
		return list;
	}
	
	@SuppressWarnings("unchecked")
	public List<Stage> getStages()
	{
		List<Stage> temp = session.createQuery("FROM Stage GROUP BY cost").list();

		List<Stage> list = new ArrayList<Stage>();
		
		for (Stage e : temp)
		{
			list.add(e.clone());
		}
		
		return list;
	}

	@SuppressWarnings("unchecked")
    public List<Launch> getLaunches()
    {
        List<Launch> list = session.createQuery("FROM Launch").list();
        
        return list;
    }
	
	public void saveLaunch(Launch launch)
	{
		if (launch != null)
		{
			Transaction tx = session.beginTransaction();
			session.save(launch);
            try {
                tx.commit();
            }
            catch(Exception e) {
                tx.rollback();
            }
		}
	}
	
	public void saveRocket(Rocket r)
	{
		if (r != null)
		{
			Transaction tx = session.beginTransaction();
			
			if (r instanceof RocketDecorator)
			{
				if (((RocketDecorator) r).getRocketDecorator() != null)
				{
					saveRocketDecorated(((RocketDecorator) r).getRocketDecorator());
				}
			}
            session.save(r);

            try {
                tx.commit();
            }
            catch(Exception e) {
                tx.rollback();
            }
        }
	}
	
	private void saveRocketDecorated(Rocket r)
	{
		if (r instanceof RocketDecorator)
		{
			if (((RocketDecorator) r).getRocketDecorator() != null)
			{
				saveRocketDecorated(((RocketDecorator) r).getRocketDecorator());
			}
		}

		session.save(r);
	}
	
	public void savePayLoad(PayLoad payload)
	{
		if (payload != null)
		{
			Transaction tx = session.beginTransaction();
			session.save(payload);
            try {
                tx.commit();
            }
            catch(Exception e) {
                tx.rollback();
            }
		}
	}
}
